/**
 *
 */
package com.jintian.smart.kernel.common.expr.format;


import com.jintian.smart.kernel.common.expr.format.reader.ElementReader;
import com.jintian.smart.kernel.common.expr.format.reader.ElementReaderFactory;

import java.io.IOException;
import java.io.StringReader;
import java.nio.CharBuffer;

/**
 * 表达式读取器
 */
public class ExpressionReader extends StringReader {

    private int currentIndex = 0;// 当前索引

    private int markIndex = 0;// 被标记后索引

    private boolean prefixBlank = false;// 与上一个读到的ElementToken之间是否有空格

    public ExpressionReader(String s) {
        super(s);
    }

    /**
     * 取得当前位置
     *
     * @return
     */
    public int getCruuentIndex() {
        return currentIndex;
    }

    /**
     * Element之前是否有空格
     *
     * @return
     */
    public boolean isPrefixBlank() {
        return prefixBlank;
    }

    @Override
    public int read() throws IOException {
        int c = super.read();
        if (c != -1) {
            currentIndex++;
            markIndex++;
        }
        return c;
    }

    @Override
    public int read(char[] cbuf) throws IOException {
        int c = super.read(cbuf);
        if (c > 0) {
            currentIndex += c;
            markIndex += c;
        }
        return c;
    }

    @Override
    public int read(CharBuffer target) throws IOException {
        int c = super.read(target);
        if (c > 0) {
            currentIndex += c;
            markIndex += c;
        }
        return c;
    }

    @Override
    public int read(char[] cbuf, int off, int len) throws IOException {
        int c = super.read(cbuf, off, len);
        if (c > 0) {
            currentIndex += c;
            markIndex += c;
        }
        return c;
    }

    @Override
    public void reset() throws IOException {
        super.reset();
        currentIndex = currentIndex - markIndex;
    }

    @Override
    public void mark(int readAheadLimit) throws IOException {
        super.mark(readAheadLimit);
        markIndex = 0;
    }

    /**
     * 以流形式读取ExpressionToken
     *
     * @return ExpressionToken
     * @throws IOException
     * @throws FormatException
     */
    public Element readToken() throws IOException, FormatException {
        prefixBlank = false;
        while (true) {
            // 去除空格
            mark(0);// 标记
            int b = read();
            if (b == -1) {
                return null;
            }
            char c = (char) b;
            if (ElementReader.IGNORE_CHAR.indexOf(c) >= 0) {// 去除开始的空格
                prefixBlank = true;
                continue;
            }
            reset();// 重置

            // 构造一个词元读取器
            ElementReader er = ElementReaderFactory.createElementReader(this);
            return er.read(this);
        }
    }
}
